#include<stdio.h>
#include<string.h>

#include "uartToLoraFrame.h"


/*
* Function Name  : crc16(uint8_t* buf, uint8_t u8Len)
* Description    : 该函数用于生成串口帧中的校验码，被crc16(uint8_t* buf, uint8_t u8Len)调用
*                  
* Input          : - in  buf 输入数组 - u8Len  输入数组有效数据长度
*                
* Output         : 
* Return         : uint16_t类型的校验码
*/
uint16_t crc16(uint8_t* buf, uint8_t u8Len){
    uint16_t u16Crc = 0xffff;
    uint8_t u8Index = 0;
    uint8_t u8Cnt = 0;
    uint8_t u8CrcH = 0;
    uint8_t u8CrcL = 0;

    for(u8Index = 0; u8Index < u8Len; u8Index++){
		u8CrcH = (uint8_t)((u16Crc & 0xff00) >> 8);
		u8CrcL = (uint8_t)((u16Crc & 0x00ff));
		u8CrcL = u8CrcL ^ buf[u8Index];
		u16Crc = ((uint16_t)u8CrcH) << 8 | u8CrcL;

		for(u8Cnt = 0; u8Cnt < 8; u8Cnt++){
			if((u16Crc & 0x0001) == 0x0001){
				u16Crc >>= 1;
				u16Crc = u16Crc ^ 0xa001;
			}else{
				u16Crc >>= 1;
			}
		}
	}
    return u16Crc;
}

/*
* Function Name  : genMsgFrame(uint8_t* in, uint8_t* inlen, uint8_t* out, uint8_t* outlen)
* Description    : 该函数用于生成发送到LoRa模块串口的消息帧数组
*                  
* Input          : - in  输入数组 - inlen  输入数组有效数据长度
*                  - out 输出数组 - outlen 输出数组有效长度
* Output         : 
* Return         : true | false 成功或失败
*/
bool genMsgFrame(uint8_t* in, uint8_t* inlen, uint8_t* out, uint8_t* outlen){
    
    uint16_t crc;

    *outlen = *inlen + 5;
    if(*inlen > MAX_PAYLOAD_LENGTH){
        printf("data in too long! inlen = %u, outlen = %u\r\n", *inlen, *outlen);
        return false;
    }

    out[0] = 0xFA;
    out[1] = *inlen;
    memcpy(&out[2], in, *inlen);

    crc = crc16(&out[1], *inlen + 1);

    out[(*inlen) + 2] = (uint8_t)(crc >> 8);
    out[(*inlen) + 3] = (uint8_t)crc;
    out[(*inlen) + 4] = 0xF5;

    return true;

}